//  #include "../entities/cdcommands.h"

// #include "helpinfo.h"
// #include "textmessage.h"
// #include "statsgraph.h"
// #include "infobar.h"
// #include "infostats.h"
// #include "textverbosemessage.h"
// #include "exitpanel.h"
// #include "mutationpanel.h"
// #include "globalsettingspanel.h"
// #include "settingsbrainpanel.h"
// #include "settingsbodypanel.h"
// #include "hud.h"
// #include "critterview.h"
// #include "brainview.h"
// #include "speciesview.h"
#include "panel.h"

#include "canvas.h"

Canvas::Canvas()
{
	active = true;

	// mouse focus
	mouseFocus = false;
	focussedwidget = 0;

	// movable widget picking
	hasPickedwidget = false;
	pickedwidget = 0;

	// point the widget width/height pointers to the window's width/height
	v_widthP = settings->winWidth;
	v_heightP = settings->winHeight;

	// set parent pointer to 0
	parent = 0;
}

void Canvas::setDefaultZAxis()
{
	// set default z axises to panels
	unsigned int panelc = 0;
	for( childit = children.begin(); childit != children.end(); childit++ )
	{
		static_cast<Panel*>(childit->second)->zaxis = panelc;
		// update sorted drawing/clicking vector
		sortedindices.push_back(childit->first);
		panelc++;
	}
}

void Canvas::moveMouseX(unsigned int x)
{
	m_x = x;
}

void Canvas::moveMouseY(unsigned int y)
{
	m_y = y;
}

// void Canvas::moveMouse(unsigned int x, unsigned int y)
void Canvas::moveMouse()
{
	int diffx = (int)m_x-m_oldx;
	int diffy = (int)m_y-m_oldy;
	// resize
	if ( hasPickedwidget && pickedwidget->isPanel && pickedwidget->parent->isPanel && static_cast<Panel*>(pickedwidget->parent)->isResizable && static_cast<Panel*>(pickedwidget->parent)->children["resizebutton"] == pickedwidget )
	{
		
		// limits
		if ( *pickedwidget->parent->v_widthP + diffx < 10 )
			diffx = 10 - *pickedwidget->parent->v_widthP + diffx;
		if ( *pickedwidget->parent->v_heightP + diffy < 10 )
			diffy = 10 - *pickedwidget->parent->v_heightP + diffy;

		*pickedwidget->parent->v_widthP += diffx;
		*pickedwidget->parent->v_heightP += diffy;
// 		updateAbsPosition();
	}
	// move
	else if ( hasPickedwidget && pickedwidget->isMovable )
	{
		pickedwidget->translate( diffx, diffy );
	}
	else
	{
		mouseFocus = false;
		if ( mouseOverChild( &focussedwidget, m_x, m_y ) )
			mouseFocus = true;
	}
	m_oldx = m_x;
	m_oldy = m_y;
}

void Canvas::buttonPress(const unsigned int& button)
{
	if ( mouseFocus )
	{
		pickedwidget = focussedwidget;
		pickedwidget->click(button);
		hasPickedwidget = true;

		// raise panel of widget?
		Widget* w = pickedwidget;
		raisePanel(w);
		while ( w->parent != 0 )
		{
			if ( w->isPanel )
				raisePanel(w);
			w = w->parent;
		}
	}
}

void Canvas::buttonRelease(const unsigned int& button)
{
	if ( hasPickedwidget )
	{
		pickedwidget->release(button);
		hasPickedwidget = false;
	}
}

void Canvas::raisePanel(Widget* w)
{
	Panel* rp = static_cast<Panel*>(w);
	if ( rp->zaxis > 0 )
	{
		// the other lower zaxis values get ++
		for( childit = children.begin(); childit != children.end(); childit++ )
		{
			Panel* p = static_cast<Panel*>(childit->second);
			if ( p->zaxis < rp->zaxis )
				p->zaxis++;
		}
		// this zaxis goes to 0
		rp->zaxis = 0;

		// resort sortedindices
		for ( int i = sortedindices.size(); i>0; i--  )
			for ( int j = 0; j < i-1; j++  )
				if ( static_cast<Panel*>(children[sortedindices[j]])->zaxis < static_cast<Panel*>(children[sortedindices[j+1]])->zaxis )
				{
					std::string keepS	= sortedindices[j];
					sortedindices[j]	= sortedindices[j+1];
					sortedindices[j+1]	= keepS;
				}
	}
}

void Canvas::draw()
{
	if ( active )
	{	
		updateAbsPosition();
		

// 		glPushMatrix();
// 		glTranslatef(0.5f, -0.5f, 0.0f); // pixel precision offset
		drawChildren();
// 		glPopMatrix();
	}
}

void Canvas::drawChildren()
{
	// draw the ordered panels
	for( unsigned int i=0; i < sortedindices.size(); i++ )
	{
		Panel* p = static_cast<Panel*>(children[sortedindices[i]]);
		if ( !p->isAlwaysOnTop )
			p->draw();
	}
	// draw the ordered panels
	for( unsigned int i=0; i < sortedindices.size(); i++ )
	{
		Panel* p = static_cast<Panel*>(children[sortedindices[i]]);
		if ( p->isAlwaysOnTop )
			p->draw();
	}
}

bool Canvas::mouseOverChild(Widget** fWidget, int x, int y)
{
	for ( int i = sortedindices.size()-1; i >= 0; i--  )
 	{
		Widget* w = children[sortedindices[i]];
		if ( (w->isTouchable && w->active && w->mouseOver(x, y)) || !w->isTouchable )
		{
			// RECURSIVE INTO CONTAINERS
			if ( w->isContainer )
			{
				Container* c = static_cast<Container*>(w);
				if ( c->mouseOverChild( fWidget, x, y ) )
				{
					return true;
				}
				else if ( w->isTouchable )
				{
					*fWidget = w;
					return true;
				}
			}
			else if ( w->isTouchable )
			{
				*fWidget = w;
				return true;
			}
		}
	}
	return false;
}

void Canvas::swapChild(const std::string& child)
{
// 	cerr << "swapping child " << child << endl;
	children[child]->swap();
	if ( children[child]->active )
		raisePanel(children[child]);

	if ( children[child]->isMovable )
	{
		if ( children[child] == pickedwidget )
			hasPickedwidget = false;
	}
	moveMouseX(m_oldx);
	moveMouseY(m_oldy);
	moveMouse();
// 	moveMouse(m_oldx, m_oldy);
}

Canvas::~Canvas()
{
}
